(function() {
	
	
	/**
	 * 绑定函数的this
	 */
	function bindScope(obj, func) {
		return function() {
			return func.apply(obj, arguments);
		}
	}
	
	function clone(o) {
		var obj = {};
		for (var name in o) {
			obj[name] = o[name];
		}
		return obj;
	}
	
	/**
	 * 对脚本进行处理以替换一些全局对象
	 */
	function safeEvalApp(appCode, vars) {

		var s = "(function(";

		var args = [];
		if (vars) {
			var i = 0;
			for (var name in vars) {
				if (i == 0) {
					s += name;
				} else {
					s += "," + name;
				}
				args.push(vars[name]);
				i++;
			}
//			for (var i = 0; i < vars.length; i++) {
//				if (i == 0) {
//					s += vars[i];
//				} else {
//					s += "," + vars[i];
//				}
//			}
		}

		s += "){ return ";
		s += appCode;
		s += "})"
		
		var f = eval(s);
		return f.apply(null, args);
	}
	
	/**
	 * 为对象创建一个代理对象,通过代理对象能且只能访问原对象的全部函数。
	 * 这可以有效地防止对原对象的非法篡改
	 */
	function ObjectGuard(obj) {
		var o = obj;
		for (var name in o) {
			var prop = o[name];
			if (typeof prop == "function") {
				this[name] = bindScope(o, prop);
			} else {
				this[name] = prop;
			}
		}
	}
	
	function Pipe() {
		var cache = [];
		var _callbacks = [];
		this.write = function(o) {
			cache.push(o);
			for (var i = 0; i < _callbacks.length; i++) {
				var item = _callbacks[i];
				item.fn.call(item.scope);
			}
		};
		this.read = function() {
			return cache.shift();
		};
		this.available = function() {
			return cache.length;
		};
		this.addListener = function(callback, scope) {
			_callbacks.push({
				fn : callback,
				scope : scope
			});
		};
		this.removeListener = function(callback, scope) {
			for (var i = 0; i < _callbacks.length; i++) {
				var item = _callbacks[i];
				if (item.fn === callback && item.scope === scope) {
					_callbacks.splice(i, 1);
					return;
				}
			}
		};
	}
	
		
	
	function AppContext(os) {
		var _os = os; 
		/** 应用的标准输出 */
		this.stdout = null;
		this.pid = null;
		this.appInstance = null;
		
		this.clear = function() {
			_os = null;
		}
		this.createApp = function() {
			return _os.createApp();
		}
		this.createPipe = function() {
			return _os.createPipe();
		}
		this.exit = function(pid, code) {
			_os.exitApp(pid, code);
		}
		this.version = function() {
			return _os.version();
		}
		
		this.shadow = function() {
			var obj = new ObjectGuard(this);
			delete obj["shadow"];
			delete obj["clear"];
			return obj;
		}
	}



	
	
	var uid = 0;
	// 在App的代码里需要屏蔽的全局对象
	var globalObjectNeedHide = ["document", "window", "alert", "$"];
	// 保存了全部App的引用
	var allApp = [];
	// 系统消息监听器
	var _systemListeners = [];
	
	function fireSystemEvent(name, param) {
		for (var i = 0; i < _systemListeners.length; i++) {
			var item = _systemListeners[i];
			item.fn.call(item.scope, name, param);
		}
	}


	osCore = {
		
		addSystemListeners : function(fn, scope) {
			_systemListeners.push({
				fn : fn,
				scope : scope
			});
		},
		
		createApp : function(appCode, args) {
			// 创建App工厂
			try {
				var args = {};
				for (var i = 0; i < globalObjectNeedHide.length; i++) {
					args[globalObjectNeedHide[i]] = undefined;
				}
				var appFactory = safeEvalApp(appCode, args);
				if (typeof appFactory != 'function') {
					throw "";
				}
			} catch (e) {
				throw e;
			}
			
			// 创建App上下文
			var appContext = new AppContext(this);
			appContext.stdout = this.createPipe();
			appContext.pid = uid++;
			
			// 创建App实例
			try {
				var shadowAppContext = appContext.shadow();
				appContext.appInstance = appFactory(shadowAppContext);
			} catch (e) {
				throw e;
			}
			
			// 保存App上下文
			allApp.push(appContext);
			fireSystemEvent("createApp", {
				appContext : clone(appContext)
			});
			
			// 执行App
			appContext.appInstance.run(args);
		},
		
		createPipe : function() {
			var pipe = new Pipe();
			return pipe;
		},
		
		exitApp : function(pid, code) {
			for (var i = 0; i < allApp.length; i++) {
				var appContext = allApp[i];
				if (appContext.pid == pid) {
					appContext.appInstance.exit(code);
					appContext.clear();
					allApp.splice(i, 1);
				}
			}
		},
		
		removeSystemListeners : function(fn, scope) {
			for (var i = 0; i < _systemListeners.length; i++) {
				var item = _systemListeners[i];
				if (item.fn === fn && item.scope === scope) {
					_systemListeners.splice(i, 1);
					return;
				}
			}
		},
		
		version : function() {
			return "webos 0.1";
		}
	}

})();